package com.study.recorderbutton.view;

import com.study.recorderbutton.R;
import com.study.recorderbutton.view.AudioManager.AudioStateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
/**
 * 自定义Button
 * @author Administrator
 *
 */
@SuppressLint("HandlerLeak")
public class AudioRecorderButton extends Button implements AudioStateListener {
	
	//设置上下滑动距离，以判断是否取消录音
	private static final int DISTANCE_Y_CANCEL = 50;
	//按钮正常状态(默认状态)
	private static final int STATE_NORMAL = 1;
	//正在录音状态
	private static final int STATE_RECORDING = 2;
	//想要取消录音状态
	private static final int STATE_WANT_TO_CANCEL = 3;
	//记录当前状态
	private int mCurState = STATE_NORMAL;
	//是否已经开始录音
	private boolean isRecording = false;
	
	//对话框管理工具类
	private DialogManager mDialogManager;
	//录音管理工具
	private AudioManager mAudioManager;
	//记录录音时间
	private float mTime;
	//是否触发LongClick
	private boolean mReady;

	public AudioRecorderButton(Context context) {
		this(context,null);
	}

	public AudioRecorderButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mDialogManager = new DialogManager(getContext());
		//录音文件存放地址
		String dir = Environment.getExternalStorageDirectory()+"/recorder_audios";
		mAudioManager = AudioManager.getInstance(dir);
		mAudioManager.setOnAudioStateListener(this);
		
		//为按钮添加长按监听
		setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				mReady = true;
				mAudioManager.prepareAudio();
				return false;
			}
		});
	}
	
	/**
	 * 录音完成后的回调接口
	 * @author Administrator
	 *
	 */
	public interface AudioFinishRecorderListener{
		void onFinish(float seconds, String filePath);
	}
	
	private AudioFinishRecorderListener mListener;
	
	public void setAudioFinishRecorderListener(AudioFinishRecorderListener listener){
		mListener = listener;
	}
	
	/**
	 * 获取音量大小的Runnable
	 */
	private Runnable mGetVoiceLevelRunnable = new Runnable() {
		
		@Override
		public void run() {
			while(isRecording){ //如果正在录音
				try {
					Thread.sleep(100);
					mTime += 0.1f; //录音时间计算
					mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};
	
	//录音准备
	private static final int MSG_AUDIO_PREPARED = 0X110;
	//音量发生变化
	private static final int MSG_VOICE_CHANGED = 0X111;
	//取消对话框
	private static final int MSG_DIALOG_DISMISS = 0X112;
	
	private Handler mHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MSG_AUDIO_PREPARED:
				//对话框显示应该在audio end prepare以后
				mDialogManager.showRecordingDialog();
				isRecording = true;
				//开启一个线程计算录音时间
				new Thread(mGetVoiceLevelRunnable).start();
				break;
			case MSG_VOICE_CHANGED:
				//更新音量显示
				mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));
				break;
			case MSG_DIALOG_DISMISS:
				mDialogManager.dimissDialog();
				break;
			default:
				break;
			}
		};
	};
	
	@Override
	public void wellPrepared() {
		mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);
		
	}
	
	@Override
	public boolean performClick() {
		// TODO Auto-generated method stub
		return super.performClick();
	}

	/**
	 * 处理按钮的onTouchEvent事件
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		//获取当前动作
		int action = event.getAction();
		//获得X轴坐标
		int x = (int) event.getX();
		//获得Y轴坐标
		int y = (int) event.getY();
		
		switch (action) {
		case MotionEvent.ACTION_DOWN: //手指按下
			changeState(STATE_RECORDING);
			break;
		case MotionEvent.ACTION_MOVE: //手指移动
			if(isRecording ){
				//根据x,y的坐标，判断是否想要取消
				if(wantToCancel(x,y)){
					changeState(STATE_WANT_TO_CANCEL);
				}else{
					changeState(STATE_RECORDING);
				}
			}
			break;
		case MotionEvent.ACTION_UP: //手指放开
			if(!mReady){
				reset();
				return super.onTouchEvent(event);
			}
			if(!isRecording || mTime<0.6f){ //如果录音时间少于0.6秒提示时间过短
				mDialogManager.tooShort();
				mAudioManager.cancel();
				//延迟显示对话框
				mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DISMISS, 1300);
			}else if(mCurState == STATE_RECORDING){   //正常录制结束
				mDialogManager.dimissDialog();
				mAudioManager.release();
				
				if(mListener != null){
					mListener.onFinish(mTime, mAudioManager.getCurrentFilePath());
				}
			}else if(mCurState == STATE_WANT_TO_CANCEL){ //想要取消录音
				mDialogManager.dimissDialog();
				mAudioManager.cancel();
			}
			reset();
			break;
		default:
			performClick();
			break;
		}
		
		return super.onTouchEvent(event);
	}

	/**
	 * 恢复状态及标志位
	 */
	private void reset() {
		isRecording = false;
		mReady = false;
		isRecording = false;
		mTime = 0;
		changeState(STATE_NORMAL);
	}

	/**
	 * 判断是否想要取消录音
	 * @param x
	 * @param y
	 * @return
	 */
	private boolean wantToCancel(int x, int y) {
		//手指在x轴方向超出按钮宽度
		if(x<0 || x>getWidth()){
			return true;
		}
		//手指在y轴方向超出按钮高度一段距离
		if(y<-DISTANCE_Y_CANCEL || y>getHeight()+DISTANCE_Y_CANCEL){
			return true;
		}
		return false;
	}

	/**
	 * 根据状态改变控件的属性
	 * @param state
	 */
	private void changeState(int state) {
		if(mCurState != state){
			mCurState = state;
			switch (state) {
			case STATE_NORMAL:
				setBackgroundResource(R.drawable.btn_recorder_normal);
				setText(R.string.str_recorder_normal);
				break;
			case STATE_RECORDING:
				setBackgroundResource(R.drawable.btn_recorder_recording);
				setText(R.string.str_recorder_recording);
				if(isRecording){
					mDialogManager.recording();
				}
				break;
			case STATE_WANT_TO_CANCEL:
				setBackgroundResource(R.drawable.btn_recorder_recording);
				setText(R.string.str_recorder_want_cancel);
				mDialogManager.wantToCancel();
				break;
			default:
				break;
			}
		}
		
	}

}
